package com.ruoyi.web.util;


import org.bouncycastle.crypto.digests.SM3Digest;
import org.bouncycastle.crypto.macs.HMac;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.pqc.math.linearalgebra.ByteUtils;

import java.util.Arrays;

public class SM3Utils {
    private static final String ENCODING = "UTF-8";

    /**
     * 加密（带密钥）
     * @param src 明文
     * @param key 密钥
     * @return 大写HEX字符串
     */
    public static String encrypt(String src, String key) throws Exception {
        return ByteUtils.toHexString(getEncryptByKey(src, key)).toUpperCase(); // 添加大写转换
    }

    /**
     * SM3加密（带密钥）
     * @param src 源数据
     * @param key 密钥
     * @return 加密字节数组
     */
    private static byte[] getEncryptByKey(String src, String key) throws Exception {
        byte[] srcByte = src.getBytes(ENCODING);
        byte[] keyByte = key.getBytes(ENCODING);
        KeyParameter keyParameter = new KeyParameter(keyByte);

        SM3Digest sm3 = new SM3Digest();
        HMac hMac = new HMac(sm3);
        hMac.init(keyParameter);
        hMac.update(srcByte, 0, srcByte.length);

        byte[] result = new byte[hMac.getMacSize()];
        hMac.doFinal(result, 0);
        return result;
    }

    /**
     * 验证（带密钥）
     * @param src 源数据
     * @param key 密钥
     * @param sm3HexStr 大写HEX密文
     * @return 验证结果
     */
    public static boolean verify(String src, String key, String sm3HexStr) throws Exception {
        // 统一转换为大写进行比较
        byte[] sm3HashCode = ByteUtils.fromHexString(sm3HexStr.toUpperCase());
        byte[] newHashCode = getEncryptByKey(src, key);
        return Arrays.equals(newHashCode, sm3HashCode);
    }

    /**
     * 加密（无密钥）
     * @param src 明文
     * @return 大写HEX字符串
     */
    public static String encrypt(String src) {
        return ByteUtils.toHexString(getEncryptBySrcByte(src.getBytes())).toUpperCase(); // 添加大写转换
    }

    /**
     * SM3加密（无密钥）
     * @param srcByte 源字节数组
     * @return 加密字节数组
     */
    private static byte[] getEncryptBySrcByte(byte[] srcByte) {
        SM3Digest sm3 = new SM3Digest();
        sm3.update(srcByte, 0, srcByte.length);

        byte[] encryptByte = new byte[sm3.getDigestSize()];
        sm3.doFinal(encryptByte, 0);
        return encryptByte;
    }

    /**
     * 验证（无密钥）
     * @param src 源数据
     * @param sm3HexStr 大写HEX密文
     * @return 验证结果
     */
    public static boolean verify(String src, String sm3HexStr) throws Exception {
        // 统一转换为大写进行比较
        byte[] sm3HashCode = ByteUtils.fromHexString(sm3HexStr.toUpperCase());
        byte[] newHashCode = getEncryptBySrcByte(src.getBytes(ENCODING));
        return Arrays.equals(newHashCode, sm3HashCode);
    }


}